Skip to main content

main function and startup_ keyword

main function

A program shall contain a global function named main, which is the designated start of the program in hosted environment.

It shall have one of the following forms:

  • int main () { /*body*/ }
  • int main (int argc, char* argv[]) { /*body*/ }

See Main function for more information.

main function arguments

You can get command line arguments event if you use mainfunction without argument.

The xtd::environment class grabs and keeps for you the command line arguments :

xtd::environment::command_line and xtd::environment::get_command_line_args usage

#include <xtd/xtd>

using namespace xtd;

auto main() -> int {
// Write the command line to the console output
console::write_line(environment::command_line());

console::write_line();

// Write command line arguments to the console output
for (auto arg : environment::get_command_line_args())
console::write_line(arg);
}

As you can see, even if the main function is called without arguments and if one two "three four" five are entered on the command line, you can still retrieve them.

startup::safe_run methods

xtd introduce the xtd::startup::safe_run methods which allows to have a main static method in any class with different parameters with or without return value.

startup::safe_run methods and exceptions

Even ifxtd::startup::safe_run method catch exceptions, it's preferable that you catch yourself exception. Indeed startup_ generate a generic fallback message to the output console for a console application and a generic falbback xtd::forms::dialog_exception for a GUI application.

Your code should look like this :

#include <xtd/xtd>

using namespace xtd;

namespace examples {
class program {
public:
static auto main() -> void {
try {
// your code
} catch(const std::exception& e) {
// Your catch handler
}
}
};
}

auto main() -> int {
return xtd::startup::safe_run(examples::program::main);
}

See try-block for more information.

startup::safe_run methods usage

  • Static main member function without argument and without return value.
#include <xtd/xtd>

using namespace xtd;

namespace examples {
class program {
public:
static auto main() -> void {
// Write arguments to the console output
for (auto arg : environment::get_command_line_args())
console::write_line(arg);

// return 42
environment::exit_code(42);
}
};
}

auto main() -> int {
return xtd::startup::safe_run(examples::program::main);
}
  • Static main member function without argument and with int return value.
#include <xtd/xtd>

using namespace xtd;

namespace examples {
class program {
public:
static auto main() -> int {
// Write arguments to the console output
for (auto arg : environment::get_command_line_args())
console::write_line(arg);

return 42;
}
};
}

auto main() -> int {
return xtd::startup::safe_run(examples::program::main);
}
  • Static main member function with string array argument and without return value.
#include <xtd/xtd>

using namespace std;
using namespace xtd;

namespace examples {
class program {
public:
static void main(const vector<ustring>& args) {
// Write arguments to the console output
for (auto arg : args)
console::write_line(arg);

// return 42
environment::exit_code(42);
}
};
}

auto main() -> int {
return xtd::startup::safe_run(examples::program::main);
}
  • Static main member function with string array argument and with int return value.
#include <xtd/xtd>

using namespace std;
using namespace xtd;

namespace examples {
class program {
public:
static int main(const vector<ustring>& args) {
// Write arguments to the console output
for (auto arg : args)
console::write_line(arg);

return 42;
}
};
}

auto main() -> int {
return xtd::startup::safe_run(examples::program::main);
}
  • Static main member function with int and char*[] arguments and without return value.
#include <xtd/xtd>

using namespace std;
using namespace xtd;

namespace examples {
class program {
public:
static auto main(int argc, char* argv[]) -> void {
// Write arguments to the console output
for (auto arg : {argv, argv + argc})
console::write_line(arg);

// return 42
environment::exit_code(42);
}
};
}

auto main() -> int {
return xtd::startup::safe_run(examples::program::main);
}
  • Static main member function with int and char*[] arguments and with int return value.
#include <xtd/xtd>

using namespace std;
using namespace xtd;

namespace examples {
class program {
public:
static auto main(int argc, char* argv[]) -> int {
// Write arguments to the console output
for (auto arg : {argv, argv + argc})
console::write_line(arg);

return 42;
}
};
}

auto main() -> int {
return xtd::startup::safe_run(examples::program::main);
}

startup_ keyword

xtd introduces the keyword startup_ which allows to have a main static method in any class with different parameters with or without return value.

Behind this keyword there is a main global function that call main static method in the specified class parameter with try and catch.

startup_ definition

#define startup_(main_method) \
auto main(int argc, char* argv[]) -> int {\
return xtd::startup::safe_run(main_method, argc, argv);\
}\
intptr_t __opaque_sftews__ = 0

startup_ and exceptions

Even if startup_ keyword catch exceptions, it's preferable that you catch yourself exception. Indeed startup_ generate a generic fallback message to the output console for a console application and a generic falbback xtd::forms::dialog_exception for a GUI application.

Your code should look like this :

#include <xtd/xtd>

using namespace xtd;

namespace examples {
class program {
public:
static auto main() -> void {
try {
// your code
} catch(const std::exception& e) {
// Your catch handler
}
}
};
}

startup_(examples::program::main);

See try-block for more information.

statup_ keyword usage

  • Static main member function without argument and without return value.
#include <xtd/xtd>

using namespace xtd;

namespace examples {
class program {
public:
static auto main() -> void {
// Write arguments to the console output
for (auto arg : environment::get_command_line_args())
console::write_line(arg);

// return 42
environment::exit_code(42);
}
};
}

startup_(examples::program::main);
  • Static main member function without argument and with int return value.
#include <xtd/xtd>

using namespace xtd;

namespace examples {
class program {
public:
static auto main() -> int {
// Write arguments to the console output
for (auto arg : environment::get_command_line_args())
console::write_line(arg);

return 42;
}
};
}

startup_(examples::program::main);
  • Static main member function with string array argument and without return value.
#include <xtd/xtd>

using namespace std;
using namespace xtd;

namespace examples {
class program {
public:
static void main(const vector<ustring>& args) {
// Write arguments to the console output
for (auto arg : args)
console::write_line(arg);

// return 42
environment::exit_code(42);
}
};
}

startup_(examples::program::main);
  • Static main member function with string array argument and with int return value.
#include <xtd/xtd>

using namespace std;
using namespace xtd;

namespace examples {
class program {
public:
static int main(const vector<ustring>& args) {
// Write arguments to the console output
for (auto arg : args)
console::write_line(arg);

return 42;
}
};
}

startup_(examples::program::main);
  • Static main member function with int and char*[] arguments and without return value.
#include <xtd/xtd>

using namespace std;
using namespace xtd;

namespace examples {
class program {
public:
static auto main(int argc, char* argv[]) -> void {
// Write arguments to the console output
for (auto arg : {argv, argv + argc})
console::write_line(arg);

// return 42
environment::exit_code(42);
}
};
}

startup_(examples::program::main);
  • Static main member function with int and char*[] arguments and with int return value.
#include <xtd/xtd>

using namespace std;
using namespace xtd;

namespace examples {
class program {
public:
static auto main(int argc, char* argv[]) -> int {
// Write arguments to the console output
for (auto arg : {argv, argv + argc})
console::write_line(arg);

return 42;
}
};
}

startup_(examples::program::main);

Windows main definitions

In Windows, there are different definitions for main in addition to the c++ standard :

main definitions in the standard c++ :

  • int main () { /*body*/ }
  • int main (int argc, char* argv[]) { /*body*/ }
  • int main (int argc, wchar_t* argv[], char* envp[ ]) { /*body*/ }

main definitions specific Windows :

  • int wmain () { /*body*/ }
  • int wmain (int argc, wchar_t* argv[]) { /*body*/ }
  • int wmain (int argc, wchar_t* argv[], wchar_t* envp[ ]) { /*body*/ }
  • int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nCmdShow);
  • int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow);

See Using wmain and WinMain: The Application Entry Point for more information

For xtd portability, the /ENTRY:mainCRTStartup flag is added automatically when you add the xtd library in your CMakeLists.txt to the linker flags. So even for a GUI application you can call the main functions of the c++ standard in the Windows development environment.

If you are not using CMake for your project creation, it is advisable to add this flag manually.

See also